﻿using System;
using System.Linq;
using System.IO;
using NAudio.Midi;
using PT.NoteDetection;
using PT.NoteDetection.Wave;

namespace PT.UI.Console {
    public class Program {

        static void Main(string[] args) {
            string inputPath = string.Empty, outputPath = string.Empty;
            int tempo = 90;

            // Process arguments
            for (int i = 0; i < args.Length - 1; ++i) {
                string arg = args[i];

                if (arg == "-i") {
                    inputPath = args[i + 1];
                    ++i;
                }
                else if (arg == "-o") {
                    outputPath = args[i + 1];
                    ++i;
                }
                else if (arg == "-t") {
                    tempo = int.Parse(args[i + 1]);
                    ++i;
                }
            }

            if (string.IsNullOrEmpty(outputPath) && !string.IsNullOrEmpty(inputPath)) {
                outputPath = string.Format("{0}\\{1}.out.txt", 
                    Path.GetDirectoryName(inputPath),
                    Path.GetFileNameWithoutExtension(inputPath));
            }

            bool appendToOutput = args.Contains("-a");

            // Missing arguments - return
            if (string.IsNullOrEmpty(inputPath) || string.IsNullOrEmpty(outputPath)) {
                System.Console.WriteLine(
                    "Usage: {0} -t <tempo> -i <inputFilePath> -o <outputFilePath> [-a]",
                    System.Diagnostics.Process.GetCurrentProcess().ProcessName);
                
                return;
            }
            
            try {
                System.Console.WriteLine("Analyzing file: " + inputPath);
                System.Console.WriteLine("Writing output to: " + outputPath);

                // Analyze file
                AnalyzeFile(inputPath, outputPath, appendToOutput, tempo);
            } 
            catch (Exception e) {
                System.Console.WriteLine(e);
            }

            return;
        }

        static void AnalyzeFile(string inputPath, string outputPath, bool appendToOutput, int tempo) {
            using (var fs = new FileStream(inputPath, FileMode.Open, FileAccess.Read)){
                using (var sr = new StreamWriter(outputPath, appendToOutput)){

                    var dc = new DetectionController {
                        Capture = new WaveStreamAudioCapture(fs)
                    };

                    dc.InitializeComponenets();
                    dc.Tempo = tempo;

                    sr.WriteLine("Analyzing file: \"{0}\"", inputPath);
                    sr.WriteLine("Detector: {0}", dc.Detector);
                    sr.WriteLine("Tempo: {0}", dc.Tempo);

                    sr.WriteLine("t - Time (ms), v - Velocity (0..127)");

                    dc.NoteDetected += 
                        delegate(object s, NoteDetectedEventArgs e) {
                            var n = e.Note;
                        
                            if (n.CommandCode == MidiCommandCode.NoteOn) {
                                var t = dc.TimeService.CalculateTime(e.Note.AbsoluteTime);
                                var v = e.Note.Velocity;
                                sr.WriteLine("{0, 13}, {1, 3}", (long)t.TotalMilliseconds, v);
                            }
                        };

                    dc.Start();
                }
            }
        }
    }
}
